Skip to content

Add option in raster plot to crop around centroids #1047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 16, 2025

Conversation

ValentinGebhart
Copy link
Collaborator

@ValentinGebhart ValentinGebhart commented Apr 15, 2025

Changes proposed in this PR:

  • Add an optional parameter to geo_im_from_array such that the user can input a (relative) distance above which plot locations that are further away than this distance from any centroids are masked (ie, no values plotted). This option is then available in all function that call geo_im_from_array, i.e., _event_plot, hazard.plot_intensity, hazard.plot_fraction, plot_from_gdf, hazard.plot_rp_intensity, impact.plot_rp_imp
  • removed bug about the NaN legend in geo_im_from_array

PR Author Checklist

PR Reviewer Checklist

@ValentinGebhart
Copy link
Collaborator Author

ValentinGebhart commented Apr 15, 2025

Example 1: plot_intensity with floods in France

from climada.util.api_client import Client
client = Client()
properties = {"country_iso3alpha": "FRA", "climate_scenario": "historical"}
hazard = client.get_hazard(hazard_type="river_flood", properties=properties)

Results:

hazard.plot_intensity(event=0, mask_distance=None)

original_fra

hazard.plot_intensity(event=0)

crop_01fra

hazard.plot_intensity(event=0, mask_distance=0.001)

crop_001fra

Example 2: some return period maps with few centroids

plot_from_gdf(ex_impact_with_zeros, colorbar_name=label, title_subplots=col_label, mask_distance=None)

orignial_imp

plot_from_gdf(ex_impact_with_zeros, colorbar_name=label, title_subplots=col_label)

crop_01_imp

plot_from_gdf(ex_impact_with_zeros, colorbar_name=label, title_subplots=col_label, mask_distance=0.01)

crop_001_imp

@ValentinGebhart
Copy link
Collaborator Author

Default is now not to mask anything, so plots will look as before if user does not specify differently. Up for discussion :) @chahank @spjuhel

Comment on lines 1198 to 1202
mask_relative_distance: float, optional
Relative distance (with respect to maximal map extent in longitude or latitude) to data
points above which plot should not display values. For instance, to only plot values
at the centroids, use mask_relative_distance=0.01. If None, the plot is not masked.
Default is None.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧐 This parameter is really hard to describe. I've read it repeatedly and still need the example images to understand it.
For me it would be probably easier if it was written in a more "positive" way, something like

Suggested change
mask_relative_distance: float, optional
Relative distance (with respect to maximal map extent in longitude or latitude) to data
points above which plot should not display values. For instance, to only plot values
at the centroids, use mask_relative_distance=0.01. If None, the plot is not masked.
Default is None.
mask_relative_distance: float, optional
Only regions are plotted that are closer to any of the data points than this distance,
relative to overall plot size. For instance, to only plot values
at the centroids, use mask_relative_distance=0.01. If None, the plot is not masked.
Default is None.

Though I'm not sure, whether it's better like that.

Then: don't meant to be fuzzy but the parameter name is a somewhat awkward, don't you think?
Is it not rather relative_mask_distance? Or just mask_distance? Or what about plotting_range? (as in only plot stuff within this plotting range)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, I will change the description and the parameter name to mask_distance. Thanks!

@emanuel-schmid
Copy link
Collaborator

emanuel-schmid commented May 15, 2025

🙌 🎉
The effect of the new parameter is awesome! Imho 0.01 should be even the default. But cannot really judge that.

Only don't like the name and description too much.
And the changelog entry is missing.

Comment on lines -480 to +499
if np.any(np.isnan(x) for x in grid_im):
if np.isnan(grid_im).any():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume, this is the fix for the bug?
When does it occur? (How can it be reproduced?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the idea was that whenever grid_im has a NaN we want to include a small legend (because we plot nan values in gray). np.any(np.isnan(x) for x in grid_im) from before did not actually output a bool but a generator, such that this if condition was always True

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ValentinGebhart Thanks! You don't happen to have an example that you could point me to?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. This would be an example where we want the legend (see PR #1038):

import numpy as np
from climada.hazard import Hazard
from climada.util import HAZ_DEMO_H5 # CLIMADA's Python file
haz_tc_fl = Hazard.from_hdf5(HAZ_DEMO_H5) # Historic tropical cyclones in Florida from 1990 to 2004
haz_tc_fl.check() # Use always the check() method to see if the hazard has been loaded correctly

centroids_mask = np.array(
[ (i + j > 10) for j in range(50) for i in range(50)]
)
haz_tc_fl.centroids = haz_tc_fl.centroids.select(sel_cen=centroids_mask)
haz_tc_fl.intensity = haz_tc_fl.intensity[:, -2434:]

return_periods, label, column_label = haz_tc_fl.local_return_period([30, 40])

from climada.util.plot import plot_from_gdf
plot_from_gdf(return_periods, colorbar_name=label, title_subplots=column_label)

and here we do not want the legend but in the current develop version it would be printed as well.

haz_tc_fl.plot_intensity(event=0)

@ValentinGebhart
Copy link
Collaborator Author

Thank you @emanuel-schmid for the review and the positive feedback! I would leave the default for now so people are not too confused but happy to adapt that in the future.

@emanuel-schmid
Copy link
Collaborator

I would leave the default for now so people are not too confused but happy to adapt that in the future.

As I said, not for me to judge. But I find the default plots atm are actually more confusing than a sudden change.

@ValentinGebhart
Copy link
Collaborator Author

As I said, not for me to judge. But I find the default plots atm are actually more confusing than a sudden change.

I'd also agree with that but there might be other opinions about changing this plot by default @spjuhel @peanutfun @chahank ?

@spjuhel
Copy link
Collaborator

spjuhel commented May 15, 2025

I agree with Emanuel the plots are much clearer. (But it is not a strong opinion)

@peanutfun
Copy link
Member

I also agree that adding a default mask_distance > 0 makes the plots clearer and we can add it immediately!

@ValentinGebhart
Copy link
Collaborator Author

Thanks for the feedback! I changed the default to mask_distance=0.01. We can always change that back if we don't like it.

@emanuel-schmid from my side this would be ready to merge. Thanks!

@emanuel-schmid emanuel-schmid merged commit af793bc into develop May 16, 2025
19 checks passed
@emanuel-schmid emanuel-schmid deleted the feature/crop_raster_plots_to_centroids branch May 16, 2025 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants